import {useState} from 'react';
import {Button, Card, Flex, Form, Input, InputNumber, message, Radio, Space, Tabs, Tooltip, Typography} from 'antd';
import {CopyOutlined, HighlightOutlined, LeftOutlined, RedoOutlined, RocketTwoTone} from '@ant-design/icons'
import './index.less'
import {baseURL} from "../../utils/request.js";
import {useNavigate} from "react-router-dom";
import ReactMarkdown from 'react-markdown';
import React from 'react';
import SimpleExample from "./SimpleExample/index.jsx";

const {Paragraph} = Typography;
const {TextArea} = Input;
// 导入作文结构数据
import TextStructData from './TextStructData.json'
import AnalyseResult from "./AnalyseResult/index.jsx";

const CompositionWriting = () => {
    const navigate = useNavigate()
    const [userdefinedContentStyle, setUserdefinedContentStyle] = useState('')
    const [userdefinedEmotionalTone, setUserdefinedEmotionalTone] = useState('')

    const [emotionalToneDisabled, setEmotionalToneDisabled] = useState(false)

    const [contentStyleDisabled, setContentStyleDisabled] = useState(false)

    // 等待生成状态
    const [isLoadingDtraw, setIsLoadingDtraw] = useState(false)

    // 生成的文章数据
    const [drewContentData, setDrewContentData] = useState('')

    const [formData, setFormData] = useState({
        // 主题和关键字
        topicsAndKeywords: "放学 嬉戏",
        //     字数
        numberOfWords: 100,
        //     内容文体
        contentStyle: "记叙文",
        //     感情基调
        emotionalTone: "欢快",
        role: 'user',

    })

    // 修改主题
    const changeTopicsAndKeywords = (e) => {
        // console.log(e.target.value)
        setFormData({
            ...formData,
            topicsAndKeywords: e.target.value
        })
    }

    // 修改字数
    const changeNumberOfWords = (newNumber) => {
        // let isError = false
        // console.log(newNumber)
        // if (newNumber > 1500) {
        //     message.error('字数不能大于1500字哦🤷‍♂️')
        //     isError = true
        // }
        // if (newNumber === null) {
        //     message.error('请输入字数')
        //     isError = true
        // }
        // if (isError) {
        //     setFormData({
        //         ...formData,
        //         numberOfWords: 100
        //     })
        // } else {
        //     setFormData({
        //         ...formData,
        //         numberOfWords: newNumber
        //     })
        // }

        setFormData({
            ...formData,
            numberOfWords: newNumber
        })
    }

    // 自定义感情基调
    const changeEmotionalTone = (e) => {
        setFormData({
            ...formData,
            emotionalTone: e.target.value
        })
// setUserdefinedEmotionalTone(e.target.value)
        userdefinedEmotionalTone.length === 0 ? setEmotionalToneDisabled(false) : setEmotionalToneDisabled(true)
    }

    // 自定义文体
    const changeContentStyle = (e) => {
        // console.log(e)

        setFormData({
            ...formData,
            contentStyle: e.target.value
        })
        // console.log(formData.contentStyle)
        // setUserdefinedContentStyle(e.target.value)
        userdefinedContentStyle.length === 0 ? setContentStyleDisabled(false) : setContentStyleDisabled(true)
    }


    // 开始生成
    const startDraw = async (e, example = false) => {
        console.log(formData)
        setIsLoadingDtraw(true)
        console.log(example)
        if (example) {
            const resp = await fetch(baseURL + '/api/v1/chat/essay/init', {
                method: 'post',
                headers: {
                    'Content-Type': 'application/json;charset=utf-8',
                    Authorization: window.localStorage.getItem('token')
                },
                body: JSON.stringify(
                    {
                        model: window.localStorage.getItem('gpt'),
                        title: example,
                        controller: "false"
                    }
                )
            })

            const reader = resp.body.getReader()

            let tempDrewContentData = ''
            const textDecoder = new TextDecoder()
            while (1) {
                const {done, value} = await reader.read()
                if (done) {
                    break
                }
                const str = textDecoder.decode(value)
                console.log('示例文章', str)

                tempDrewContentData += str
                setDrewContentData(tempDrewContentData)
            }


            setIsLoadingDtraw(false)

            return
        }

        // 获取数据
        // console.log('msg',msg)
        // let res = await compositionWritingAPI(msg)

        let localData = window.localStorage.getItem('writingHistory')

        let arr = []
        if (localData) {
            arr = JSON.parse(localData)
            if (arr.length >= 5) {
                arr.shift()
            }
            arr.push(formData)

        } else {
            arr.push(formData)
        }

        const resp = await fetch(baseURL + '/api/v1/chat/essay/init/custom', {
            method: 'post',
            headers: {
                'Content-Type': 'application/json;charset=utf-8',
                Authorization: window.localStorage.getItem('token')
            },
            body: JSON.stringify(
                {

                    model: window.localStorage.getItem('gpt'),
                    messages: arr,
                    controller: "false"
                }
            )
        })

        const reader = resp.body.getReader()

        let tempDrewContentData = ''
        const textDecoder = new TextDecoder()
        while (1) {
            const {done, value} = await reader.read()
            if (done) {
                break
            }
            const str = textDecoder.decode(value)
            console.log('自定义文章', str)

            tempDrewContentData += str
            setDrewContentData(tempDrewContentData)
        }


        setIsLoadingDtraw(false)
        saveToLocal(formData)

    }
    //     将数据保存本地
    const saveToLocal = (formData) => {

        let compositionWritingHistory = window.localStorage.getItem('writingHistory')
        if (compositionWritingHistory) {
            let arr = JSON.parse(compositionWritingHistory)
            if (arr.length === 5) {
                arr.shift()
            }
            arr.push(formData)

            console.log(arr)
            window.localStorage.setItem('writingHistory', JSON.stringify(arr))
        } else {
            let arr = []
            arr.push(formData)
            console.log(arr)
            window.localStorage.setItem('writingHistory', JSON.stringify(arr))
        }
    }

    // 复制功能
    const copyText = () => {

        navigator.clipboard.writeText(drewContentData)
            .then(() => {
                console.log('复制成功');
                message.success('复制成功👻')
            })
            .catch(err => {
                console.error('复制失败', err);
                message.error('复制失败🤷‍♂️',);
            })
    }

    // 文章标题
    const [textTitle, setTextTitle] = useState('')

    // 修改title
    const changeTextTitle = (e) => {
        setTextTitle(e.target.value)
    }

    // 开始生成简易
    const startCustomDraw = async () => {

        setIsLoadingDtraw(true)
        let obj = {
            title: textTitle
        }

        // let localData = window.localStorage.getItem('writingCustomHistory')
        // let arr = []
        // console.log(localData)
        // if (localData) {
        //     arr = JSON.parse(localData)
        //     if (arr.length >= 5){
        //         arr.shift()
        //     }
        //     arr.push(arr)
        //
        // } else {
        //     arr = []
        //     arr.push(obj)
        // }

        // 获取数据
        // console.log('msg', arr)

        const resp = await fetch(baseURL + '/api/v1/chat/essay/init', {
            method: 'post',
            headers: {
                'Content-Type': 'application/json;charset=utf-8',
                Authorization: window.localStorage.getItem('token'),
                // Authorization: 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJvb2lZWTZXMW1TUUpLYXFXVGxzd2hkYXdHeXBnIiwib3BlbklkIjoib29pWVk2VzFtU1FKS2FxV1Rsc3doZGF3R3lwZyIsImV4cCI6MTcxNDQ2MDkzMiwidXNlcklkIjoiMzY3NDQ2NDI3NTI3Mjg2Nzg0IiwiaWF0IjoxNzEzODU2MTMyLCJqdGkiOiI3ZmE3YjllZS1jZjlhLTQ5YzQtOWEzMS1mMWQzNGU5M2I3ZmEifQ.5eFcsrK62ASy8ecogKBTek6TgEQsn8pOjUcue9sGI90'
            },
            body: JSON.stringify(
                {
                    model: window.localStorage.getItem('gpt'),
                    title: textTitle,
                    controller: "false"
                }
            )
        })

        const reader = resp.body.getReader()
        // let result =  resp.json()
        // console.log('11',result)
        let tempDrewContentData = ''
        const textDecoder = new TextDecoder()
        while (1) {
            const {done, value} = await reader.read()
            if (done) {
                break
            }
            const str = textDecoder.decode(value)
            console.log('简易文章', str)

            tempDrewContentData += str
            setDrewContentData(tempDrewContentData)
        }


        setIsLoadingDtraw(false)

    }

    //     将数据保存本地
    const saveCustomToLocal = (formData) => {

        let compositionWritingHistory = window.localStorage.getItem('writingCustomHistory')
        if (compositionWritingHistory) {
            let arr = JSON.parse(compositionWritingHistory)
            if (arr.length === 5) {
                arr.shift()
            }
            arr.push(formData)

            console.log(arr)
            window.localStorage.setItem('writingCustomHistory', JSON.stringify(arr))
        } else {
            let arr = []
            arr.push(formData)
            console.log(arr)
            window.localStorage.setItem('writingCustomHistory', JSON.stringify(arr))
        }
    }

    // 结构选定数据
    const [structSelectFormData, setStructSelectFormData] = useState({
        title:"",
        structName:"五段式结构"
    })

    // 作文结构数据索引
    const [structSelectIndex, setStructSelectIndex] = useState(0)



    // 根据结构生成文本
    const startStructDraw = async () => {
        setIsLoadingDtraw(true)
        // 获取数据
        // console.log('msg', arr)

        const resp = await fetch(baseURL + '/api/v1/novel/gen/article/content', {
            method: 'post',
            headers: {
                'Content-Type': 'application/json;charset=utf-8',
                Authorization: window.localStorage.getItem('token'),
                // Authorization: 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJvb2lZWTZXMW1TUUpLYXFXVGxzd2hkYXdHeXBnIiwib3BlbklkIjoib29pWVk2VzFtU1FKS2FxV1Rsc3doZGF3R3lwZyIsImV4cCI6MTcxNDQ2MDkzMiwidXNlcklkIjoiMzY3NDQ2NDI3NTI3Mjg2Nzg0IiwiaWF0IjoxNzEzODU2MTMyLCJqdGkiOiI3ZmE3YjllZS1jZjlhLTQ5YzQtOWEzMS1mMWQzNGU5M2I3ZmEifQ.5eFcsrK62ASy8ecogKBTek6TgEQsn8pOjUcue9sGI90'
            },
            body: JSON.stringify(
                {
                    model: window.localStorage.getItem('gpt'),
                    title: structSelectFormData.title,
                    construct:structSelectFormData.structName,
                    characteristic:TextStructData.TextStructData[structSelectIndex].character,
                    base:TextStructData.TextStructData[structSelectIndex].basic,
                    skill:TextStructData.TextStructData[structSelectIndex].skill,
                    scene:TextStructData.TextStructData[structSelectIndex].place,
                    controller: "false"
                }
            )
        })

        const reader = resp.body.getReader()
        let tempDrewContentData = ''
        const textDecoder = new TextDecoder()
        while (1) {
            const {done, value} = await reader.read()
            if (done) {
                break
            }
            const str = textDecoder.decode(value)
            // console.log('按照结构生成文本', str)

            tempDrewContentData += str
            setDrewContentData(tempDrewContentData)
        }
        // console.log('按照结构生成文本',tempDrewContentData)

    }


    // 待分析文本
    const [analyseText, setAnalyseText] = useState('')

    // 分析文本
    const startAnalyse = async () => {

        setIsLoadingDtraw(true)
        // 获取数据

        const resp = await fetch(baseURL + '/api/v1/novel/analyze/article/content', {
            method: 'post',
            headers: {
                'Content-Type': 'application/json;charset=utf-8',
                Authorization: window.localStorage.getItem('token'),
                // Authorization: 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJvb2lZWTZXMW1TUUpLYXFXVGxzd2hkYXdHeXBnIiwib3BlbklkIjoib29pWVk2VzFtU1FKS2FxV1Rsc3doZGF3R3lwZyIsImV4cCI6MTcxNDQ2MDkzMiwidXNlcklkIjoiMzY3NDQ2NDI3NTI3Mjg2Nzg0IiwiaWF0IjoxNzEzODU2MTMyLCJqdGkiOiI3ZmE3YjllZS1jZjlhLTQ5YzQtOWEzMS1mMWQzNGU5M2I3ZmEifQ.5eFcsrK62ASy8ecogKBTek6TgEQsn8pOjUcue9sGI90'
            },
            body: JSON.stringify(
                {
                    model: window.localStorage.getItem('gpt'),
                    article:analyseText,
                    controller: "false"
                }
            )
        })

        const reader = resp.body.getReader()
        let tempDrewContentData = ''
        const textDecoder = new TextDecoder()
        while (1) {
            const {done, value} = await reader.read()
            if (done) {
                break
            }
            const str = textDecoder.decode(value)
            console.log('分析文本', str)

            tempDrewContentData += str
            setDrewContentData(tempDrewContentData)
        }
    }

    // tab页
    const tabItems = [
        {
            key: '1',
            label: '一键生成',
            children: <Card style={{width: '100%', minHeight: '72vh'}}>

                <SimpleExample startDraw={startDraw}/>
                <div className="myform">
                    <Form layout={'vertical'}>
                        <Form.Item label={'文章题目'}>
                            <TextArea autoSize={{
                                minRows: 5,
                            }} value={textTitle} onChange={changeTextTitle} placeholder="输入文章题目"/>
                        </Form.Item>
                        <Form.Item>
                            <Button type="primary" onClick={startCustomDraw} loading={isLoadingDtraw}>
                                {!isLoadingDtraw && < RocketTwoTone/>}
                                {!isLoadingDtraw ? '生成' : "正在生成..."}
                            </Button>
                        </Form.Item>
                    </Form>
                </div>

            </Card>,
        },
        {
            key: '2',
            label: '个性化',
            children: <Card style={{width: '100%'}}>
                <div className={'myform'}>
                    <Form
                        layout={'vertical'}
                    >
                        <Form.Item label="主题和关键字">
                            <TextArea
                                autoSize={{minRows: 5}} disabled={isLoadingDtraw} value={formData.topicsAndKeywords}
                                onChange={changeTopicsAndKeywords} showCount
                                maxLength={100} placeholder="输入主题和关键字"/>
                        </Form.Item>


                        <Tooltip title="字数必须在100-1500字哦👻">
                            <Form.Item label="字数" style={{width: 100}}>
                                <InputNumber disabled={isLoadingDtraw}
                                             min={100}
                                             max={1500}
                                             addonAfter="字"
                                             defaultValue={100}
                                             onChange={changeNumberOfWords}/>
                            </Form.Item>
                        </Tooltip>


                        <Form.Item label="内容文体"
                                   style={{display: 'flex', alignItems: 'center', justifyContent: 'flex-start'}}>
                            {/*<Radio.Group defaultValue="a" size="large" buttonStyle="solid">*/}
                            {/*    <Radio.Button value="a">记叙文</Radio.Button>*/}
                            {/*    <Radio.Button value="b">议论文</Radio.Button>*/}
                            {/*    <Radio.Button value="c">小说</Radio.Button>*/}
                            {/*    <Radio.Button value="d">文言文</Radio.Button>*/}
                            {/*</Radio.Group>*/}

                            <Radio.Group disabled={contentStyleDisabled || isLoadingDtraw} defaultValue={"记叙文"}
                                         size="middle"
                                         onChange={changeContentStyle}>
                                <Radio.Button value="记叙文">记叙文</Radio.Button>
                                <Radio.Button value="说明文">说明文</Radio.Button>
                                <Radio.Button value="议论文">议论文</Radio.Button>
                                <Radio.Button value="诗歌">诗歌</Radio.Button>
                                <Radio.Button value="小说">小说</Radio.Button>
                                <Radio.Button value="散文">散文</Radio.Button>
                                <Radio.Button value="剧本">剧本</Radio.Button>
                            </Radio.Group>

                            <div style={{margin: '10px 0'}}>
                                自定义添加:
                                <Input
                                    disabled={isLoadingDtraw}
                                    onChange={(e) => {
                                        setUserdefinedContentStyle(e.target.value)
                                        userdefinedContentStyle.length === 0 ? setContentStyleDisabled(false) : setContentStyleDisabled(true)
                                    }}
                                    onPressEnter={(e) => {
                                        setUserdefinedContentStyle(e.target.value)
                                        userdefinedContentStyle.length === 0 ? setContentStyleDisabled(false) : setContentStyleDisabled(true)
                                    }}
                                    style={{
                                        width: 100,
                                        marginLeft: 10,
                                    }}
                                />
                            </div>
                        </Form.Item>

                        <Form.Item label="感情基调"
                                   style={{display: 'flex', alignItems: 'center', justifyContent: 'flex-start'}}>
                            <Radio.Group disabled={emotionalToneDisabled || isLoadingDtraw} defaultValue={"欢快"}
                                         size="middle"
                                         onChange={changeEmotionalTone}>
                                <Radio.Button value="欢快">欢快</Radio.Button>
                                <Radio.Button value="忧愁">忧愁</Radio.Button>
                                <Radio.Button value="寂寞">寂寞</Radio.Button>
                                <Radio.Button value="伤感">伤感</Radio.Button>
                                <Radio.Button value="恬淡">恬淡</Radio.Button>
                                <Radio.Button value="闲适">闲适</Radio.Button>
                                <Radio.Button value="激愤">激愤</Radio.Button>
                                <Radio.Button value="思念">思念</Radio.Button>
                            </Radio.Group>

                            <div style={{margin: '10px 0'}}>
                                自定义添加:
                                <Input
                                    disabled={isLoadingDtraw}
                                    onPressEnter={(e) => {
                                        setUserdefinedEmotionalTone(e.target.value)
                                        userdefinedEmotionalTone.length === 0 ? setEmotionalToneDisabled(false) : setEmotionalToneDisabled(true)
                                    }}
                                    onChange={(e) => {
                                        setUserdefinedEmotionalTone(e.target.value)
                                        userdefinedEmotionalTone.length === 0 ? setEmotionalToneDisabled(false) : setEmotionalToneDisabled(true)
                                    }}
                                    style={{
                                        width: 100,
                                        marginLeft: 10,
                                    }}
                                />
                            </div>
                        </Form.Item>

                        <Form.Item>
                            <Button type="primary" onClick={startDraw} loading={isLoadingDtraw}>
                                {!isLoadingDtraw && < RocketTwoTone/>}
                                {!isLoadingDtraw ? '生成' : "正在生成..."}
                            </Button>
                        </Form.Item>
                    </Form>
                </div>
            </Card>
        },
        {
            key: '3',
            label: '结构选定',
            children: <>
                <Card style={{height: 'calc(100vh - 64px)', width: '100%'}}>
                    <div className={'myform'}>
                        <Form
                            layout={'vertical'}

                        >
                            <Form.Item label="作文题目"
                                       style={{display: 'flex', alignItems: 'center', justifyContent: 'flex-start'}}>
                                <Input value={structSelectFormData.title} onChange={(e) => {
                                    setStructSelectFormData({
                                        ...structSelectFormData,
                                        title: e.target.value
                                    })
                                }}/>
                            </Form.Item>


                            <Form.Item label="作文结构"
                                       style={{display: 'flex', alignItems: 'center', justifyContent: 'flex-start'}}>

                                <Radio.Group disabled={contentStyleDisabled || isLoadingDtraw} defaultValue={0}
                                             size="small"
                                             onChange={(e) => {
                                                 setStructSelectIndex(e.target.value)
                                                 setStructSelectFormData({
                                                     ...structSelectFormData,
                                                     structName: TextStructData.TextStructData[e.target.value].structName
                                                 })
                                                 console.log(structSelectFormData)
                                             }}>
                                    {TextStructData.TextStructData.map((item, index) =>
                                        (
                                            <Tooltip key={item.structName} title={item.detail}>
                                                <Radio.Button value={index}>{item.structName}</Radio.Button>
                                            </Tooltip>

                                        )
                                    )}
                                </Radio.Group>

                            </Form.Item>

                            <Form.Item label="结构说明"
                                       style={{display: 'flex', alignItems: 'center', justifyContent: 'flex-start'}}>
                                <Paragraph>
                                    <Typography.Title
                                        level={5}
                                        style={{
                                            margin: 0,
                                        }}
                                    >
                                        特点
                                    </Typography.Title>
                                    <blockquote>{TextStructData.TextStructData[structSelectIndex]?.character}</blockquote>

                                    <Typography.Title
                                        level={5}
                                        style={{
                                            margin: 0,
                                        }}
                                    >
                                        基本要求
                                    </Typography.Title>
                                    <blockquote>{TextStructData.TextStructData[structSelectIndex]?.basic}</blockquote>

                                    <Typography.Title
                                        level={5}
                                        style={{
                                            margin: 0,
                                        }}
                                    >
                                        写作技巧
                                    </Typography.Title>
                                    <blockquote>{TextStructData.TextStructData[structSelectIndex]?.skill}</blockquote>

                                    <Typography.Title
                                        level={5}
                                        style={{
                                            margin: 0,
                                        }}
                                    >
                                        适合场景
                                    </Typography.Title>
                                    <blockquote>{TextStructData.TextStructData[structSelectIndex]?.place}</blockquote>
                                </Paragraph>
                            </Form.Item>


                            <Form.Item >
                                <Button type="primary" onClick={startStructDraw} loading={isLoadingDtraw}>
                                    {!isLoadingDtraw && < RocketTwoTone/>}
                                    {!isLoadingDtraw ? '生成' : "正在生成..."}
                                </Button>
                            </Form.Item>
                        </Form>
                    </div>
                </Card>
            </>
        },
        {
            key: '4',
            label: '结构分析',
            children: (
                <div>
                    <Card style={{width: '100%'}}>
                        <div className={'myform'}>
                            <Form
                                layout={'vertical'}
                            >
                                <Form.Item label="待分析文本">
                                    <TextArea
                                        autoSize={{minRows: 25}} disabled={isLoadingDtraw} value={analyseText}
                                        showCount
                                        placeholder="输入需要分析的文本"
                                        onChange={(e) => {
                                           setAnalyseText(e.target.value)
                                        }}
                                    />
                                </Form.Item>


                                <Form.Item>
                                    <Button
                                        type="primary"
                                        loading={isLoadingDtraw}
                                        onClick={startAnalyse}
                                    >
                                        {!isLoadingDtraw && < RocketTwoTone/>}
                                        {!isLoadingDtraw ? '分析' : "正在分析..."}
                                    </Button>
                                </Form.Item>
                            </Form>
                        </div>
                    </Card>
                    {/*<AnalyseResult/>*/}
                </div>
            )
        },
    ];


    const [currentTabIndex, setCurrentTabIndex] = useState(1)


// 改变tab页
    const changeTab = (key) => {
        setDrewContentData('')
        console.log(key);
        setCurrentTabIndex(key)
    };


// 一键精修跳转页面
    const oneTapModify = () => {
        navigate('/WorkPlace/TextPolishing', {state: {text: drewContentData}})
    }





    return (
        <div>

            <Card>
                {drewContentData.length === 0 &&
                    <Tabs type="card" defaultActiveKey="1" items={tabItems} onChange={changeTab}/>}
            </Card>




            {/*生成结果*/}
            {drewContentData &&
                <Card
                    style={{width: '100%',textAlign:'start'}}
                    extra={
                        <Flex justify={'space-between'} style={{width: '100%'}}>


                            <Button type={'primary'} onClick={() => {
                                setDrewContentData('')
                                setIsLoadingDtraw(false)
                            }}>
                                <LeftOutlined/>
                                返回
                            </Button>


                            <Space size={"middle"}>

                                <Button type={'primary'} onClick={oneTapModify}>
                                    <HighlightOutlined/>
                                    一键精修
                                </Button>

                                <Button type={'primary'} onClick={copyText}>
                                    <CopyOutlined/>
                                </Button>

                                <Button type={'primary'} onClick={() => {
                                    setDrewContentData('')
                                    setTextTitle('')
                                    if (currentTabIndex == 2) {
                                        startDraw()
                                    } else {
                                        startCustomDraw()
                                    }
                                }}>
                                    <RedoOutlined/>
                                </Button>
                            </Space>
                        </Flex>
                    }
                >
                    {/*<Typography>*/}
                    {/*    /!*<Paragraph>*!/*/}
                    {/*    /!*    /!*<blockquote>{blockContent}</blockquote>*!/*!/*/}
                    {/*    /!*    <pre> {drewContentData}</pre>*!/*/}
                    {/*    /!*</Paragraph>*!/*/}
                    {/*</Typography>*/}
                    <ReactMarkdown style={{
                        textAlign: 'start'
                    }}>
                        {drewContentData}
                    </ReactMarkdown>
                </Card>}
        </div>


    );
};
export default CompositionWriting;
